<template>
  <div class="main-right">
  <el-row>
    <h1 v-if="this.$route.path==='/PCM_AutomationViewer/edit'">{{editTestCaseTitle}}</h1>
    <h1 v-if="this.$route.path==='/PCM_AutomationViewer/add'">{{addTestCaseTitle}}</h1>
    <el-form :model="testCaseForm" label-width="220px" :rules="TestCaseRules" ref="testCaseForm" style="margin:80px;min-width:900px;">
      <el-form-item label="Test Case Name" prop="testCaseName" style="width: 50%;" status-icon>
        <el-input v-if="this.$route.path==='/PCM_AutomationViewer/edit'" v-model="testCaseForm.testCaseName" auto-complete="off" ref="testCaseForm.testCaseName"></el-input>
        <el-input v-else v-model="testCaseForm.testCaseName" auto-complete="off" clearable ref="testCaseForm.testCaseName"></el-input>
      </el-form-item>
      <el-form-item label="Test Case Id" v-if="this.$route.path==='/PCM_AutomationViewer/edit'" prop="testCaseId" style="width: 40%;" >
        <el-input v-model="testCaseForm.testCaseId" auto-complete="off" :disabled="true"></el-input>
      </el-form-item>
      <!--<bizKey :bizKey="testCaseForm.bizKey"></bizKey>-->
      <el-row  v-for="(bizKey, index) in testCaseForm.bizKey">
        <el-col :span="6">
          <el-form-item :label="'BizKey'+(index+1)"  :prop="'bizKey.'+ index + '.bizKeyType'"
                        :rules="{required: true, message: 'At least one Biz Key is required.', trigger: 'change'}"
          >
            <el-autocomplete
              v-model="bizKey.bizKeyType"
              :fetch-suggestions="querySearchBizKeyType"
              size="small"
              style="min-width:200px; width:auto;"
              auto-complete="on"
              clearable
              placeholder="type"
              v-on:input="bizKeyTypeTransform(bizKey.bizKeyType,index)"
            ></el-autocomplete>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item :prop="'bizKey.'+ index + '.bizKeyValue'"
                        :rules="{required: true, message: 'At least one Biz Key is required.', trigger: 'blur'}">
            <el-input style="width: 300px;" size="small" placeholder="value" v-model="bizKey.bizKeyValue" auto-complete="off" clearable
            ></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="2">
          <el-form-item>
            <el-button type="danger" @click.prevent="removeBizKey(bizKey)" icon="el-icon-delete" size="mini">Delete BizKey</el-button>
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="Message In" prop="msgIn" >
        <el-button size="small" type="text" v-on:click="inputMsgModal=true">Input Message</el-button>
        <el-dialog title="Input Message"
                   :visible.sync="inputMsgModal"
                   effect="fade" width="50%"
                   backdrop="true"
                   :close-on-click-modal="false">
          <el-input class="input-with-select" type="textarea" :autosize="{ minRows: 2, maxRows: 5}" auto-complete="off" v-model="testCaseForm.msgIn" clearable></el-input>
          <div slot="footer">
            <el-button type="primary" class="btn btn-default" v-on:click="inputMsgModal = false">OK</el-button>
          </div>
        </el-dialog>
      </el-form-item>
      <el-form-item label="In Queue" prop="inQueue" style="width: 40%;">
        <el-input v-model="testCaseForm.inQueue" auto-complete="off" clearable></el-input>
      </el-form-item>
      <el-row v-for="(url, index) in testCaseForm.urls" :prop="'urls.'+ index + '.url'">
        <el-col :span="17">
          <el-form-item :label="'Url'+(index+1)" >
          <div align="left" >
            <el-autocomplete
              v-model="url.url"
              :fetch-suggestions="querySearchUrl"
              size="small"
              auto-complete="on"
              style="width: 600px"
              clearable
            ></el-autocomplete>
          </div>
          </el-form-item>
        </el-col>
        <el-col :span="3">
          <el-form-item>
            <div align="left">
                <el-button type="primary" @click.prevent="removeDomain(url)" icon="el-icon-delete" size="mini">Delete url</el-button>
            </div>
          </el-form-item>
        </el-col>

      </el-row>
      <el-form-item label="Verifier" >
        <div align="left">
          <el-checkbox-group @change="controlVerifierItems" v-model="testCaseForm.verifiers" size="mini" fill="#1fc7ff">
            <el-checkbox-button label="Message Verifier"></el-checkbox-button>
            <el-checkbox-button label="DB Verifier"></el-checkbox-button>
            <el-checkbox-button label="MongoDB Verifier"></el-checkbox-button>
          </el-checkbox-group>
        </div>
      </el-form-item>
        <el-form-item label="Msg out of oracle db verifier" v-if="dbVerifier" :rules="{required: true, message: 'Out Message of DB is required.', trigger: 'blur'}" prop="msgOut.dbVerifier">
          <el-input
            :autosize="{ minRows: 2, maxRows: 4}"
            style="width: 500px"
            type="textarea"
            v-model="testCaseForm.msgOut.dbVerifier"
            placeholder="please input "
            auto-complete="off"
            class="input-with-select"
            clearable>
          </el-input>
        </el-form-item>
      <el-row v-if="msgVerifier">
        <el-col :span="5">
          <el-form-item label="Msg out of message verifier"
                        prop="outQueue" :rules="{required: true, message: 'Out Queue is required', trigger: 'blur'}">
            <el-input v-model="testCaseForm.outQueue" auto-complete="off" clearable placeholder="Out Queue" style="width:300px;"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="10">
          <el-form-item  prop="msgOut.messageVerifier" :rules="{required: true, message: 'Out Message is required.', trigger: 'blur'}">
            <el-input
              :autosize="{ minRows: 2, maxRows: 4}"
              type="textarea"
              style="width:500px;"
              v-model="testCaseForm.msgOut.messageVerifier"
              placeholder="please input "
              auto-complete="off"
              class="input-with-select"
              clearable>
            </el-input>
          </el-form-item>
        </el-col>
      </el-row>
        <el-form-item :required="true" label="Msg out of mongo db verifier" v-if="mongoVerifier" v-for="(collection,index) in mongoCollections">
          <el-button size="small" type="text" v-on:click="inputMongoMsg(index,collection)">input mongo verifier message{{index+1}}</el-button>
          <el-button type="primary" @click.prevent="removeCollection(collection)" icon="el-icon-delete" size="mini"></el-button>
        </el-form-item>
      <el-form-item label="Tag" style="width:90%">
        <div align="left">
          <el-row>
            <el-col>
              <el-tag
                :key="tag"
                v-for="tag in testCaseForm.tags"
                closable
                :disable-transitions="false"
                @close="handleClose(tag)">
                {{tag}}
              </el-tag>
            </el-col>
            <el-col :span="3">
              <el-autocomplete  v-model="tag" class="inline-input"
                :fetch-suggestions="querySearchTag"
                v-if="inputTagVisible"
                ref="saveTagInput"
                size="small"
                @keyup.enter.native="handleInputConfirm"
              ></el-autocomplete>
              <el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
            </el-col>
          </el-row>
        </div>
      </el-form-item>
      <el-form-item align="left" size="small" >
        <el-button class="submitGroup" type="primary" v-on:click.native="submitTestCase" :disabled="submitButton" >Submit</el-button>
        <el-button class="el-button--danger" type="primary" v-on:click.native="openRelationshipDialog" :disabled="submitButton" >temp relationship</el-button>
        <el-button @click="addBizKey()" icon="el-icon-plus" type="primary">Add BizKey</el-button>
        <el-button @click="addUrl()" icon="el-icon-plus" type="primary">Add Url</el-button>
        <el-button @click="addMongoCollection()" v-if="mongoVerifier" icon="el-icon-plus" type="primary" >Add Collection</el-button>
      </el-form-item>
    </el-form>
    <mongoCollectionDialog :mongoCollection=mongoCollection :mongoVerifierModal="mongoVerifierModal" @onMongoVerifierModal="onMongoVerifierModal">
    </mongoCollectionDialog>
    <router-view></router-view>
  </el-row>
    <relationship-page v-bind:testCase="testCaseForm" v-bind:showRelationshipDialog="showRelationshipDialog" v-on:hideRelationShipDialog="removeDialog"></relationship-page>
  </div>
</template>

<script>
  /* eslint-disable */
  //  import { bus } from '../eventbus.js'
  import relationshipPage from './Relationship.vue'
  import mongoCollectionDialog from './TestCase/MongoCollectionDialog.vue'

  export default {
    data() {
      let checkTestCaseName = (rule, value, callback) => {
        if (!value) {
          callback(new Error('Test Case Name is required.'));
        }
        else if (this.$route.params.name === 'copy' || this.$route.params.name === 'add') {
            this.verifyTestCaseName(value, callback);
        }
        else if (value !== this.editTestCaseOriginalName){
          this.verifyTestCaseName(value, callback);
        }
        else {
          callback();
        }
      };
      let checkUrl = (rule, value, callback) => {
        if (!value) {
          callback(new Error('please input url'));
        }
        else {
          callback();
        }
      };
      return {
        checkTestCaseName : checkTestCaseName,
        dbVerifier : '',
        msgVerifier : '',
        mongoVerifier : '',
        tempVerifiers : [],
        relationshipSnapshot:'',
        showRelationshipDialog: false,
        inputMsgModal: false,
        mongoCollections: [{
          table: '',
          criteria: [{
            key: '',
            value: ''
          }]
        }],
        mongoCollection: {
          table: '',
          criteria: [{
            key: '',
            value: ''
          }]
        },
        mongoTable: [],
        criteria: [],
        mongoVerifierModal: false,
        editTestCaseTitle: 'Edit Test Case',
        addTestCaseTitle: 'Add Test Case',
        inputTagVisible: false,
        tag: '',
        tagOptions: [],
        urlList: [],
        bizKeyTypeList:[],
        submitButton: false,
        editTestCaseOriginalName: '',
        options: [{
          value: 'restful',
          label: 'restful'
        }, {
          value: 'soap',
          label: 'soap'
        }],
        testCaseForm: {
          testCaseId: '',
          testCaseName: '',
          bizKey: [{
            type: '',
            value: ''
          }],
          msgIn: '',
          msgOut:
            {
              dbVerifier: '',
              mongoDBVerifier: '',
              messageVerifier: '',
            }
          ,
          inQueue: '',
          outQueue: '',
          urls: [],
          verifiers: [],
          tags: [],
          relationship:{
            dependency:[],
            testCaseId:'',
          },
          isReady: false
        },
        TestCaseRules: {
          testCaseName: [
            {required: true, validator: checkTestCaseName, trigger: 'blur'}
          ],
          bizKey: [
            {required: true, message: 'please input bizKey', trigger: 'blur'}
          ],
          msgIn: [
            {required: true, message: 'Input Message is required.', trigger: 'blur'}
          ],
          inQueue: [
            {required: true, message: 'In Queue is required.', trigger: 'blur'}
          ],
          outQueue: [
            {required: true, message: 'Out Queue is required.', trigger: 'blur'}
          ],
          msgOut: [
            {required: true, message: 'please select', trigger: 'blur'}
          ]
        },
        verifierRules: {
          dbVerifier: [
            {required: true, message: 'please input', trigger: 'blur'}
          ],
        }
      }
    },
    components: {
      relationshipPage,
      mongoCollectionDialog
    },
    methods: {
      onMongoVerifierModal :function (val) {
        this.mongoVerifierModal = val;
      },
      verifyTestCaseName: function(value, callback) {
        let url = 'testcase/name/' + value;
        this.$http.get(url).then((res) => {
          if (res.body.data) {
            callback(new Error('sorry, the test case name already exist , please input again!'));
          }
          else if (res.body.status === '400') {
            this.$message({
              message: res.body.reason,
              type: 'error'
            });
          }
          else {
            callback();
          }
        })
      },
      clearVerifierContentWhenCancel : function () {
        if(this.testCaseForm.verifiers.indexOf(this.msgVerifier) === -1) {
          this.testCaseForm.outQueue = '';
          this.testCaseForm.msgOut.messageVerifier = '';
        }
        if(this.testCaseForm.verifiers.indexOf(this.dbVerifier) === -1) {
          this.testCaseForm.msgOut.dbVerifier= '';
        }
        if(this.testCaseForm.verifiers.indexOf(this.mongoVerifier) === -1) {
          this.mongoCollections = [];
          this.addMongoCollection();
        }
      },
      controlVerifierItems: function (val) {
        this.msgVerifier = '';
        this.dbVerifier = '';
        this.mongoVerifier = '';
        let msgVerifier = "Message Verifier";
        let dbVerifier = "DB Verifier";
        let mongoVerifier = "MongoDB Verifier";
        if (val.indexOf(msgVerifier) !== -1) {
          this.msgVerifier = msgVerifier;
        }
        if (val.indexOf(dbVerifier) !== -1) {
          this.dbVerifier = dbVerifier;
        }
        if(val.indexOf(mongoVerifier) !== -1){
          this.mongoVerifier = mongoVerifier;
        }
      },

      removeDialog: function (relationship) {
        this.showRelationshipDialog = false;
        if(relationship !== null) {
          this.testCaseForm.relationship = relationship;
        }
      },
      showInput: function () {
        this.inputTagVisible = true;
        this.$nextTick(_ => {
          this.$refs.saveTagInput.$refs.input.focus();
        });
      },
      handleClose: function (tag) {
        this.testCaseForm.tags.splice(this.testCaseForm.tags.indexOf(tag), 1);
      },
      handleInputConfirm: function () {
        let inputValue = this.tag;
        if (inputValue) {
          if (this.testCaseForm.tags.indexOf(inputValue.toLowerCase()) !== -1) {
            this.$message({
              type: 'error',
              message: 'Tag exist, please input another one!'
            })
          }
          else {
            this.testCaseForm.tags.push(inputValue.toLowerCase());
          }
        }
        this.inputTagVisible = false;
        this.inputValue = '';
      },
      querySearchTag: function (queryString, cb) {
        this.commonQuerySearch(queryString, this.tagOptions, cb);
      },
      querySearchUrl: function (queryString, cb) {
        this.commonQuerySearch(queryString, this.urlList, cb);
      },
      querySearchBizKeyType: function (queryString, cb) {
        this.commonQuerySearch(queryString, this.bizKeyTypeList, cb);
      },
      createFilter: function (queryString) {
        return (option) => {
          return (option.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1);
        };
      },
      submitEdit: function (url, para) {
        para.isReady = para.isReady && JSON.stringify(para.relationship) == this.relationshipSnapshot;
        this.$http.put(url, {params: para}).then((res) => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            });
          } else {
            this.$message({
              message: 'Edit test case submit success',
              type: 'success'
            });
            this.$router.push({path: '/PCM_AutomationViewer/TestCaseTable'});
          }
        });
      },
      submitAdd: function (url, para) {
        this.$http.post(url, {params: para}).then((res) => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            })
          } else {
            this.$message({
              message: 'Add test case submit success!',
              type: 'success'
            });
            this.$refs.testCaseForm.resetFields();
          }
        })
      },
      submitTestCase: async function () {
        if(!await this.containAllDependencyBizKey()){
          return ;
        }
        this.$refs.testCaseForm.validate((valid) => {
          if(this.testCaseForm.verifiers.indexOf('MongoDB Verifier') !== -1){
            this.mongoCollections.forEach(item => {
              if(item.table.length === 0 ){
                valid = false;
                this.$message({
                  type:'warn',
                  message:'MongoDB Criteria is required.'
                });
              }
            });
          }
          if (valid) {
            this.$confirm('Are you sure', 'Tip', {}).then((res) => {
              this.clearVerifierContentWhenCancel();
              this.spliceMongoMsg();
              this.testCaseForm.msgOut.mongoDBVerifier = JSON.stringify(this.mongoTable);
              let para = Object.assign({}, this.testCaseForm);
              this.addBizKeyType();
              if (this.$route.path === '/PCM_AutomationViewer/edit') {
                let url = 'testcase/edit';
                this.submitEdit(url, para);
              } else {
                let url = 'testcase/add';
                this.submitAdd(url, para);
              }
            }).catch((e) => {
              this.$message({
                type:'error',
                message:e
              })
            })
          }
        })
      },
      openRelationshipDialog: function() {
        this.showRelationshipDialog = true;
      },
      addBizKeyType: function () {
        let url = 'bizKey/addBizKeyType';
        this.$http.post(url, {params: this.testCaseForm.bizKey}).then((res) => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            })
          }
        })
      },
      removeDomain: function (item) {
        let index = this.testCaseForm.urls.indexOf(item)
        if (index !== -1) {
          this.testCaseForm.urls.splice(index, 1)
        }
      },
      removeBizKey: function (item) {
        let index = this.testCaseForm.bizKey.indexOf(item)
        if (this.testCaseForm.bizKey.length>1) {
          this.testCaseForm.bizKey.splice(index, 1)
        } else {
            this.$message({
              type:'error',
              message:'At least one Biz Key is required.'
            })
        }
      },
      removeCollection: function (item) {
        if(this.mongoCollections.length > 1){
          let index = this.mongoCollections.indexOf(item);
          if (index !== -1) {
            this.mongoCollections.splice(index, 1);
          }
        } else {
          this.$message({
            type:'error',
            message:'At least one mongo collection is required , or please cancel choose the mongo verifier selection.'
          })
        }

      },
      addUrl: function () {
        this.testCaseForm.urls.push({
          url: '',
        });
      },
      addBizKey: function () {
        this.testCaseForm.bizKey.push({
          bizKeyType: '',
          bizKeyValue: ''
        })
      },
      addMongoCollection: function () {
        this.mongoCollections.push({
          table: '',
          criteria: [{
            key: '',
            value: ''
          }]
        })
      },
      initializeTagOption: function () {
        let url = 'testcase/tagList';
        this.$http.get(url).then(res => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            })
          } else {
            for (let i = 0; i < res.body.length; i++) {
              this.tagOptions.push({
                value: res.body[i]
              })
            }
          }
        })
      },
      spliceMongoMsg: function () {
        this.mongoTable = [];
        this.mongoCollections.forEach(item => {
          item.criteria.forEach(item1 => {
            this.criteria.push('\"' + item1.key + '\"' + ':' + '\"' + item1.value + '\"');
          });
          this.mongoTable.push({
            table: item.table,
            criteria: JSON.parse('{' + this.criteria.join() + '}')
          });
          //需要清空否则会把前table的criteria值传到下个table
          this.criteria = [];
        });
      },
      extractMongoMsg: function () {
        if (this.testCaseForm) {
          let mongoMsg = JSON.parse(this.testCaseForm.msgOut.mongoDBVerifier);
          mongoMsg.forEach(item => {
            Object.getOwnPropertyNames(item.criteria).forEach((val, idx, array) => {
              this.criteria.push({
                key: val,
                value: item.criteria[val]
              })
            });
            this.mongoTable.push({
              table: item.table,
              criteria: this.criteria,
            })
            this.criteria = [];
          });
          this.mongoCollections = this.mongoTable;
        }
      },
      initializeEditSituation: function () {
        if (this.$route.path === '/PCM_AutomationViewer/edit') {
          if (this.$route.params.data) {
            this.testCaseForm = this.$route.params.data;
            var relationship = {
              dependency: this.$route.params.data.relationship.dependency,
              testCaseId: this.$route.params.data.relationship.testCaseId,
            };
            this.testCaseForm.relationship = relationship;
            this.relationshipSnapshot = JSON.stringify(relationship);
            this.editTestCaseOriginalName = this.$route.params.data.testCaseName;
            let msgOut = this.testCaseForm.msgOut;
            this.mongoVerifier = JSON.parse(msgOut.mongoDBVerifier)[0].table? "MongoDB Verifier" : "";
            this.dbVerifier = msgOut.dbVerifier? "DB Verifier" : "";
            this.msgVerifier = msgOut.messageVerifier? "Message Verifier" : "";
            this.extractMongoMsg();
          } else {
            this.$router.push('/PCM_AutomationViewer/TestCaseTable');
          }
        }
      },
      initializeCopySituation: function () {
        if (this.$route.params.name === 'copy') {
          this.testCaseForm = this.$route.params.data;
          this.mongoVerifier = JSON.parse(this.testCaseForm.msgOut.mongoDBVerifier)[0].table? "MongoDB Verifier" : "";
          this.dbVerifier = this.testCaseForm.msgOut.dbVerifier? "DB Verifier" : "";
          this.msgVerifier = this.testCaseForm.msgOut.messageVerifier? "Message Verifier" : "";
          this.extractMongoMsg();
        }
      },
      initializeTestCaseVue: function () {
        this.initializeEditSituation();
        this.initializeCopySituation();
      },
      getUrlList: function () {
        let url = 'urls/urlList';
        this.$http.get(url).then(res => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            })
          } else {
            for (let i = 0; i < res.body.length; i++) {
              this.urlList.push({
                value: res.body[i].url
              })
            }
          }
        })
      },
      getBizKeyTypeList: function () {
        let url = 'bizKey/getAllBizTypes';
        this.$http.get(url).then(res => {
          if (res.body.status === '400') {
            this.$message({
              type: 'error',
              message: res.body.reason
            })
          } else {
            for (let i = 0; i < res.body.data.length; i++) {
              this.bizKeyTypeList.push({
                value: res.body.data[i].type
              })
            }
          }
        })
      },
      inputMongoMsg:  function (index, collection) {
        this.mongoCollection = collection;
        this.mongoVerifierModal = true;
      },
      bizKeyTypeTransform: function (value,index) {
        this.testCaseForm.bizKey[index].bizKeyType = value.toLowerCase();
      },
      commonQuerySearch: function (queryString, targetList, cb) {
        let results = queryString ? targetList.filter(this.createFilter(queryString)) : targetList;
        cb(results);
      },
      containAllDependencyBizKey : async function () {
        let dependency = this.testCaseForm.relationship.dependency;
        let testcaseIds = [];
        this.getAllTestcaseIds(testcaseIds,dependency);
        let dependencyBizKeys = await this.asynGetAllDependencyBizKey(testcaseIds);
        return this.checkContainAllDependencyBizKey(dependencyBizKeys);
      },
      getAllTestcaseIds : function (testcaseIds,dependency) {
        let me = this
        if(!dependency || dependency.length <= 0){
          return ;
        }
        dependency.forEach(function (item) {
          testcaseIds.push(item.testCaseId);
          me.getAllTestcaseIds(testcaseIds,item.dependency);
        })
      },
     asynGetAllDependencyBizKey : function (testcaseIds) {
       if(!testcaseIds || testcaseIds.length <= 0){
         return [];
       }
       let me = this
       let testcaseIdsStr = testcaseIds.toString();
       let url = 'testcase/getAllDependencyBizKeysByTestcaseIds/'+testcaseIdsStr;
       return new Promise(function (resolve, reject) {
         me.$http.get(url).then(res => {
           if (res.body.status === '500') {
             me.$message({
               type: 'error',
               message: 'get data error in DataAccess.'
             })
           } else {
             resolve(res.body.data)
           }
         })
       })
      },
      checkContainAllDependencyBizKey : function (dependencyBizKeys) {
        let currentBizTypes = [];
        this.testCaseForm.bizKey.forEach(item=>{
          currentBizTypes.push(item.bizKeyType);
        })
        let nonExistTypes = [];
        if(dependencyBizKeys && dependencyBizKeys.length >0){
          dependencyBizKeys.forEach(item=>{
            if (currentBizTypes.indexOf(item) === -1) {
              nonExistTypes.push(item);
            }
          })
        }
        if (nonExistTypes.length === 0) {
          return true;
        }else{
          this.$message({
            type: 'error',
            message: 'Missing Biz Key type "'+nonExistTypes.toString()+'" to match the relationship.'
          });
          return false;
        }
      }
    },

    mounted() {

    },
    created() {
      this.initializeTagOption();
      this.initializeTestCaseVue();
      this.getUrlList();
      this.getBizKeyTypeList();
    }
  };
</script>
<style>
  .el-select .el-input {
    width: 650px;
  }
  .input-with-select .el-input-group__prepend {
    background-color: #ffffff;
  }
  .main-right{
    margin-top:50px;
    border: solid 40px #E9ECF1;  background-color: #FCFCFC;
    padding: 50px 70px; }
  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }

  svg.leader-line {
    z-index: 9999;
  }
</style>
